package com.xc.sys.service;

import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.xc.common.object.PageInfo;
import com.xc.common.tool.BeanAid;
import com.xc.common.tool.Helper;
import com.xc.db.tables.SysRole;
import com.xc.db.tables.records.SysRoleRecord;
import com.xc.sys.entity.SysRoleEntity;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.apache.commons.lang3.StringUtils;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SelectForUpdateStep;
import org.jooq.SelectSeekStepN;
import org.jooq.SortField;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SysRoleService {
	@Autowired
	private DSLContext dsl;
	private SysRole SYSROLETB = SysRole.SYS_ROLE.as("SYSROLETB");

	public Result<Record> select(Condition whr, PageInfo<SysRoleEntity> pageInfo, SortField<?>... orderby) {
		SelectSeekStepN<Record> seek = dsl.select().from(SYSROLETB).where(whr).orderBy(orderby);
		Result<Record> result = null;
		if (pageInfo != null) {
			SelectForUpdateStep<Record> su = seek.limit(pageInfo.getLimit()).offset(pageInfo.getBeginNum());
			result = su.fetch();
		} else {
			result = seek.fetch();
		}
		if (pageInfo != null) {
			pageInfo.setResult(result);
			pageInfo.setList(result.into(SysRoleEntity.class));
		}
		return result;
	}

	public List<SysRoleEntity> select(Condition whr, SortField<?>... orderby) {
		Result<Record> result = dsl.select().from(SYSROLETB).where(whr).orderBy(orderby).fetch();
		List<SysRoleEntity> list = Lists.newArrayList();
		if (result.size() > 0) {
			list = result.into(SysRoleEntity.class);
		}
		return list;
	}

	public Long count(Condition cond) {
		Long count = dsl.selectCount().from(SYSROLETB).where(cond).fetchOneInto(Long.class);
		return count;
	}

	public Record getRecordById(Long id) {
		Record record = dsl.select().from(SYSROLETB).where(SYSROLETB.ID.eq(id)).fetchOne();
		return record;
	}

	public SysRoleEntity getEntityById(Long id) {
		Record r = getRecordById(id);
		if(r==null) {
			return null;
		}
		SysRoleEntity entity = r.into(SysRoleEntity.class);
		return entity;
	}

	public String update(SysRoleEntity entity) {
		SysRoleRecord record = new SysRoleRecord();
		record.from(entity);
		dsl.executeUpdate(record);
		roleCache.invalidate(entity.getId());
		nameCache.invalidate(entity.getName());
		return entity.getId();
	}


	public String insert(SysRoleEntity entity) {
		SysRoleRecord record = new SysRoleRecord();
		String id = Helper.getSnowId() + "";
		entity.setId(id);
		record.from(entity);
		roleCache.invalidate(entity.getId());
		nameCache.invalidate(entity.getName());
		dsl.executeInsert(record);
		return id;
	}

	public String save(SysRoleEntity entity) {
		if (StringUtils.isEmpty(entity.getId())) {
			return insert(entity);
		}
		return update(entity);
	}

	public void deleteById(Long id) {
		SysRoleEntity entity = getEntityById(id);
		roleCache.invalidate(id);
		nameCache.invalidate(entity.getName());
		dsl.delete(SYSROLETB).where(SYSROLETB.ID.eq(id)).execute();
	}
	public static LoadingCache<Long, Optional<SysRoleEntity>> roleCache = CacheBuilder.newBuilder()
			.maximumSize(5000).build(new CacheLoader<Long, Optional<SysRoleEntity>>() {
				public Optional<SysRoleEntity> load(Long id) {
					SysRoleService service = BeanAid.getBean(SysRoleService.class);
					SysRoleEntity user = service.getEntityById(id);
					return Optional.fromNullable(user);
				}
			});

	public static SysRoleEntity getFromCaches(Long key) {
		if (key == null) {
			return null;
		}
		try {
			return roleCache.get(key).orNull();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static LoadingCache<String, Optional<SysRoleEntity>> nameCache = CacheBuilder.newBuilder()
			.maximumSize(5000).build(new CacheLoader<String, Optional<SysRoleEntity>>() {
				public Optional<SysRoleEntity> load(String name) {
					SysRoleService service = BeanAid.getBean(SysRoleService.class);
					List<SysRoleEntity> list = service.select(DSL.field("NAME").eq(name));
					SysRoleEntity en = null;
					if(list.size()==1) {
						en = list.get(0);
					}
					return Optional.fromNullable(en);
				}
			});
	
	public static SysRoleEntity getFromNameCaches(String key) {
		if (key == null) {
			return null;
		}
		try {
			return nameCache.get(key).orNull();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static LoadingCache<String, Optional<SysRoleEntity>> codeCache = CacheBuilder.newBuilder()
			.maximumSize(5000).build(new CacheLoader<String, Optional<SysRoleEntity>>() {
				public Optional<SysRoleEntity> load(String code) {
					SysRoleService service = BeanAid.getBean(SysRoleService.class);
					List<SysRoleEntity> list = service.select(DSL.field("CODE").eq(code));
					SysRoleEntity en = null;
					if(list.size()==1) {
						en = list.get(0);
					}
					return Optional.fromNullable(en);
				}
			});
	
	public static SysRoleEntity getFromCodeCaches(String key) {
		if (key == null) {
			return null;
		}
		try {
			return codeCache.get(key).orNull();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return null;
	}
}
